/*
    Dominate 3D - A cube-based game of life

    Copyright (C) 2007, Craig H. Miller (kidmosey@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FONT_H__
#define __FONT_H__

#include <GL/glew.h>
#include "tga.h"
//#include "float4.h"

class GLFont
{
public:
    GLFont(const char fname[])
            : m_fontImage(fname)
    {
        m_base  = 0;
        m_texID = 0;

        CreateTexture();
        BuildFont();
    }

    ~GLFont()
    {
        if (glIsList(m_base))
            glDeleteLists(m_base, 256);
    }

    void Draw(int x, int y, const char text[] /*, float color[4] */) const
    {
        //glColor4fv((GLfloat *)color);

        glPushMatrix();

        glEnable(GL_TEXTURE_2D);	// Enable Texture Mapping
        //Enable2D();

        glTranslated(x,y,0); // Position The Text (0,0 - Bottom Left)
        glListBase(m_base);  // Choose The Font Set (0 or 1)

        //glScalef(1.5f,2.0f,1.0f);	// Enlarge Font Width And Height
        //glScalef(4.5f,4.0f,4.0f);	// Enlarge Font Width And Height

        glEnable(GL_BLEND);
        //glEnable(GL_ALPHA_TEST);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glBindTexture(GL_TEXTURE_2D, m_texID);            // Select Our Font Texture
        glCallLists(strlen(text),GL_UNSIGNED_BYTE, text); // Write The Text To The Screen

        glDisable(GL_BLEND);

        //Disable2D();
        glDisable(GL_TEXTURE_2D);				// Disable Texture Mapping
        glPopMatrix();
    }

protected:
    void CreateTexture()
    {
        // Create Texture
        glGenTextures(1, &m_texID);
        glBindTexture(GL_TEXTURE_2D, m_texID);   // 2d texture (x and y size)

        // scale linearly when image bigger than texture
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

        // scale linearly when image smalled than texture
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

        /* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from
          image, y size from image,
           border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
        */
        glTexImage2D(
            GL_TEXTURE_2D, 0, GL_RGBA8,
            m_fontImage.GetWidth(),
            m_fontImage.GetHeight(),
            0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
            m_fontImage.GetData());
    }

    void BuildFont()
    {
        float cx,cy;
        float f=15.0f/256.0f;

        m_base=glGenLists(256);				// Creating 256 Display Lists
        for (int loop1=0; loop1<256; loop1++)
        {		// Loop Through All 256 Lists
            cx=(float)(loop1%16)/16.0f;			// X Position Of Current Character
            cy=(float)(loop1/16)/16.0f;			// Y Position Of Current Character

            glNewList(m_base+loop1,GL_COMPILE);		// Start Building A List
            //glBindTexture(GL_TEXTURE_2D, m_texID);	// Select Our Font Texture
            glBegin(GL_QUADS);				// Use A Quad For Each Character

            glTexCoord2f(cx,1.0f-cy-f);		// Texture Coord (Bottom Left)
            glVertex2i(0,0);				// Vertex Coord (Top Left)

            glTexCoord2f(cx+f,1.0f-cy-f);	// Texture Coord (Bottom Right)
            glVertex2i(16,0);				// Vertex Coord (Top Right)

            glTexCoord2f(cx+f,1.0f-cy);		// Texture Coord (Top Right)
            glVertex2i(16,16);			// Vertex Coord (Bottom Right)

            glTexCoord2f(cx,1.0f-cy);			// Texture Coord (Top Left)
            glVertex2i(0,16);				// Vertex Coord (Bottom Left)

            glEnd();					// Done Building Our Quad (Character)
            glTranslated(15,0,0);			// Move To The Right Of The Character
            glEndList();				// Done Building The Display List
        }						// Loop Until All 256 Are Built
    }
/*
    void Enable2D()
    {
        int viewPort[4];        // Get the current viewport dimensions

        glGetIntegerv(GL_VIEWPORT, viewPort); // Select the projection matrix
        glMatrixMode(GL_PROJECTION);  // Push the current projection matrix

        glPushMatrix();    //save matrix
        glLoadIdentity();

        glOrtho(0, viewPort[2], 0, viewPort[3], -1, 1);

        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity(); //reset modelview matrix

    }

    void Disable2D()
    {
        // Select the projection matrix
        glMatrixMode(GL_PROJECTION);

        // Pop the current projection matrix to return to
        // perspective mode, our original projection matrix
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
    }
*/

private:
    CTGA   m_fontImage;
    GLuint m_texID;
    GLuint m_base;
};


#endif // __FONT_H__
